'''
Created on Aug 13, 2012

@author: petrina
'''
import logging


try:
    import matplotlib.pylab as pylab
    from matplotlib.dates import DateFormatter,DayLocator, HourLocator
except:
    # some systems might not have it
    logging.warning("cannot import pylab -- for plotting you have to install this library")

from error.output_exceptions import Plot_exception


class Plot(object):
    '''
    Class for managing the plots (used by other classes such as Indicator).
    
    The class uses pylab (--> you might need to install it).
    
    In order to export to a *.png-File do the following:
        - init Plot
        - call create_new_plot()-method 
        - call plot()
        - call save_plot2png() in order to export the plot
    
    '''


    def __init__(self, path = '../output/'):
        '''
        
        @param path: directory (default: ../output/)
        '''
        
        self.__fig = None
        self.__dpi = 100
        self.__path = path
        
        logging.debug("Plot: created new pylab-based Plot with the export path " + path)
        
        
    #----------------------public methods of the class-------------------------
    
    def create_new_plot(self, title = '', xlabel='', ylabel = ''):
        '''
        Creates a new figure with a grid and the given titles.
        
        @param title: title of the plot (written on the top)
        @param xlabel: title of the x-axis (e.g. time)
        @param ylabel: title of the y-axis (e.g. speed)
        '''
        
        logging.debug("Plot: creating new plot-figure")
        
        self.__fig = pylab.figure()
        #parmeter for figue() : num=None, figsize=(8, 6), dpi=DPI, facecolor='w', edgecolor='k'
        pylab.grid()
        pylab.xlabel(xlabel)
        pylab.ylabel(ylabel)
        pylab.title(title)
    
    def save_plot2png(self, filename, ext):
        """ 
        Tries to export the current chart to png.
        
        If the path is not valid or saving is for another reason not possible 
        a Plot_exception will be raised. The filepath is constructed from the
        default directory path (@see path) and the filename (@see filename)
       """
        file = self.__path+filename+"."+ext
        try:
            logging.info("Plot: trying to save the figure to the path " + file)
            pylab.savefig(file, dpi=self.__dpi, format=ext)
        except:
            logging.error("Plot: unable to save the figure at " + file)
            raise  Plot_exception("unable to save the plot at " + file)
        
        
        
    def plot(self, xvalues, yvalues, col='red', mark='+', markersize = 3):
        '''
        plots the given values in a 2D-plot
        
        @param xvalues: list with x-values 
        @param yvalues: list with y-values
        @param col: color of the line (default: red)
        @param mark: symbol of the marker (default: +) 
        @param markersize: size of the marker (default: 3)
        '''
        
        logging.debug("Plot: trying to plot the given value-pairs x=" + xvalues.__str__() + "; y=" + yvalues.__str__())
        
        pylab.plot(xvalues,yvalues,marker = mark, ms=markersize, color = col)
        
        
    def plot_date(self, xvalues, yvalues, col='red', mark='+', markersize = 3, fmt=None):
        '''
        similar to plot but with a datetime x-axis.
        
        @param xvalues: list with x-values 
        @param yvalues: list with y-values
        @param col: color of the line (default: red)
        @param mark: symbol of the marker (default: +) 
        @param markersize: size of the marker (default: 3)
        @param fmt: alternative marker attribute for pylab  
        '''
        ax = pylab.subplot(111)
        
        if fmt is None: 
            pylab.plot_date(pylab.date2num(xvalues),yvalues,marker = mark, ms=markersize, color = col)
        else:
            pylab.plot_date(pylab.date2num(xvalues),yvalues,fmt, color = col)
        pylab.gca().xaxis.set_major_locator(DayLocator()) 
        pylab.gca().xaxis.set_major_formatter(DateFormatter('%b %d'))
        
        labels = ax.get_xticklabels()
        pylab.setp(labels, rotation=30, fontsize=10)
        
        for tick in pylab.gca().xaxis.iter_ticks():
            #tick[0].label2On = True
            #tick[0].label1On = False
            tick[0].label.set_rotation('vertical')
 